#include "VideoProcessor.h"
#include "core/gamestream/XComponentBackend.h"
#include "core/utils/AVUtils.h"
#include <multimedia/player_framework/native_avcodec_videodecoder.h>

#undef LOG_DOMAIN
#undef LOG_TAG
#define LOG_DOMAIN  0x0
#define LOG_TAG     "VideoProcessor"
#include <hilog/log.h>


VideoProcessor::VideoProcessor(XComponentBackend *xcomp, OHNativeWindow *nativeWindow) :
        xcomp(*xcomp), nativeWindow(nativeWindow),
        renderHandleLoop(std::thread(&VideoProcessor::handleRender, this)) {
}

VideoProcessor::~VideoProcessor() {
    decodeReadyCond.notify_all();
    renderReadyCond.notify_all();
    renderHandleLoop.join();
    if (decoder) {
        AV_CALL_OR_ELSE(OH_VideoDecoder_Destroy(decoder),);
    }
}

void VideoProcessor::handleRender() {
    while (!xcomp.stopFlag) {
        std::unique_lock l(renderMtx);
        renderReadyCond.wait(l, [&] { return !renderQueue.empty() || xcomp.stopFlag; });
        if (xcomp.stopFlag) {
            break;
        }
        // TODO drop frame when latency is too high
        while (!renderQueue.empty()) {
            if constexpr (DEBUG) {
                OH_LOG_DEBUG(LOG_APP, "Handling render of buffer %{public}d, %{public}d total", renderQueue.front().index, renderQueue.size());
            }
            AV_CALL_OR_ELSE(OH_VideoDecoder_RenderOutputBuffer(decoder, renderQueue.front().index),);
            renderQueue.pop_front();
        }
    }
    OH_LOG_DEBUG(LOG_APP, "%{public}s ending handleRender", xcomp.id.c_str());
}
